﻿using ConfClient;
using System.IO;
using gpb = global::Google.Protobuf;

namespace SvCore.Tcp
{

    public partial class MyPackage
    {
        public uint ProtocolId { get; set; }
        public short Ecode { get; set; }
        public byte[] Body { get; set; }

        public EProtocolResult ECode => (EProtocolResult)Ecode;

        public static MyPackage From<T>(T msg, EProtocolResult ecode = EProtocolResult.成功) where T : gpb.IMessage
        {
            var pack = new MyPackage();
            pack.ProtocolId = CoreHash.HashMsg<T>();
            pack.Ecode = (short)ecode;

            MemoryStream msgStream = new MemoryStream();
            gpb::CodedOutputStream outputStream = new gpb::CodedOutputStream(msgStream);
            msg.WriteTo(outputStream);
            outputStream.Flush();
            pack.Body = msgStream.ToArray();

            return pack;
        }
        public byte[] Encode()
        {
            var DataSize = 4 + 2 + Body.Length;
            var Data = new byte[4 + DataSize];

            Data[0] = (byte)(DataSize & 0xff);
            Data[1] = (byte)((DataSize & 0xff00) >> 8);
            Data[2] = (byte)((DataSize & 0xff0000) >> 16);
            Data[3] = (byte)((DataSize & 0xff000000) >> 24);

            Data[4] = (byte)(ProtocolId & 0xff);
            Data[5] = (byte)((ProtocolId & 0xff00) >> 8);
            Data[6] = (byte)((ProtocolId & 0xff0000) >> 16);
            Data[7] = (byte)((ProtocolId & 0xff000000) >> 24);

            Data[8] = (byte)(Ecode & 0xff);
            Data[9] = (byte)((Ecode & 0xff00) >> 8);

            int index = 4 + 4 + 2;
            while (index < 4 + DataSize)
            {
                Data[index] = Body[index - (4 + 4 + 2)];
                index++;
            }

            return Data;
        }
        public T GetMsg<T>() where T : gpb::IMessage<T>, new()
        {
            var t = new T();
            t.MergeFrom(new gpb::CodedInputStream(Body));
            return t;
        }
        public void GetMsg<T>(out T t) where T : gpb::IMessage<T>, new()
        {
            t = new T();
            t.MergeFrom(new gpb::CodedInputStream(Body));
        }
    }

}

